using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using bitzhuwei.Compiler;

namespace bitzhuwei.AnsiCFormat {
    /// <summary>
    /// Correspond to the Vn node pointer in the grammar(AnsiC).
    /// </summary>
    internal partial class Vnpointer : IFullFormatter {
        // [138]=pointer : '*' ;
        // [139]=pointer : '*' type_qualifier_list ;
        // [140]=pointer : '*' pointer ;
        // [141]=pointer : '*' type_qualifier_list pointer ;


        private readonly Token last0;
        private readonly Vntype_qualifier_list? last1;
        private readonly List<Token> list0 = new();
        private readonly List<Vntype_qualifier_list?> list1 = new();

        private readonly TokenRange _scope;
        public TokenRange Scope => _scope;

        public void Format(TextWriter writer, FormatContext context) {
            throw new NotImplementedException();
        }

        public void FullFormat(BlankConfig preConfig, TextWriter writer, FormatContext context) {
            var count = this.list0.Count;
            var config = new BlankConfig(inlineBlank: 1, forceNewline: false);

            for (var i = 0; i < count; i++) {
                var item0 = this.list0[i];
                var item1 = this.list1[i];
                context.PrintBlanksAnd(item0, i == 0 ? preConfig : config, writer);
                if (item1 != null) {
                    context.PrintCommentsBetween(item0, item1, config, writer);
                    context.PrintBlanksAnd(item1, config, writer);
                    if (i + 1 < count) {
                        context.PrintCommentsBetween(item1, this.list0[i + 1], config, writer);
                    }
                    else {
                        context.PrintCommentsBetween(item1, this.last0, config, writer);
                    }
                }
                else {
                    if (i + 1 < count) {
                        context.PrintCommentsBetween(item0, this.list0[i + 1], config, writer);
                    }
                    else {
                        context.PrintCommentsBetween(item0, this.last0, config, writer);
                    }
                }
            }
            {
                context.PrintBlanksAnd(this.last0, count > 0 ? config : preConfig, writer);
                if (this.last1 != null) {
                    context.PrintBlanksAnd(this.last1, config, writer);
                }
            }
        }

        public IEnumerable<string> YieldTokens(TextWriter writer, FormatContext context) {
            throw new NotImplementedException();
        }
        internal Vnpointer(Token last1, Vntype_qualifier_list? last0) {
            this.last0 = last1;
            this.last1 = last0;
            if (last0 != null) { this._scope = new TokenRange(last1, last0); }
            else { this._scope = new TokenRange(last1); }
        }

        internal void Insert(Token r2, Vntype_qualifier_list? r1) {
            this.list0.Insert(0, r2);
            this.list1.Insert(0, r1);
            this._scope.start = r2.index;
        }

    }
}
